# -*- coding: utf-8 -*-
"""
Created on Tue Nov 24 18:01:47 2020

@author: xyz
"""

#必备的包
import sys
import os
from PyQt5.QtWidgets import QWidget, QApplication, QFileDialog, QMessageBox
#fit界面的其他子界面
from window import MainWin
from odeawin import Ui_OdeAWin
from fitresultwin import Ui_fitresult
#nlmixr的包
from nlmixr import *

class OdeAwin(QWidget, Ui_OdeAWin):
    # 手动创建模型的子窗口
    def __init__(self):
        super().__init__()
        self.setupUi(self)

class FitResultWin(QWidget, Ui_fitresult):
    # 显示数据结果的窗口
    def __init__(self):
        super().__init__()
        self.setupUi(self)
    
        
class Fit(MainWin):
    def __init__(self):
        super().__init__()  
        #创建一个手动构建模型的子窗口
        self.ode_a = OdeAwin()
        #创建一个显示数据结果的窗口
        self.fit_result = FitResultWin()
        #点击加载数据的按钮加载数据
        self.tb.clicked.connect(self.openfile)
        self.tb.clicked.connect(self.loadfile)
        #打开手动构建模型的子窗口
        self.ode_ab.clicked.connect(self.show_ode_a)
        #在窗口中获取模型参数并创建，创建完成后关闭
        self.ode_a.okb.clicked.connect(self.create_it)
        self.ode_a.cb.clicked.connect(self.ode_a.close)
        #选择算法，返回算法名称
        self.choose.currentIndexChanged.connect(self.choose_it)
        #开始拟合数据
        self.beginb.clicked.connect(self.show_fit_result)
        self.beginb.clicked.connect(self.fit_it)
        #显示拟合数据的表格
        self.fit_result.sb.clicked.connect(self.display_fit_data)
        self.fit_result.sb.clicked.connect(self.fit_result.close)
        self.fit_result.sb.clicked.connect(self.clean_fit_result)
        #关闭拟合数据窗口
        self.fit_result.cb.clicked.connect(self.fit_result.close)
        self.fit_result.cb.clicked.connect(self.clean_fit_result)
    
    def show_ode_a(self):
        #显示手动创建模型的子窗口
        self.ode_a.show()
        
    def show_ode_b(self):
        #显示自动创建模型的子窗口
        pass
    
    def show_fit_result(self):
        self.fit_result.show()
        
    def openfile(self):
        #打开文件
        self.fname = QFileDialog.getOpenFileName(self,'请选择文件','','*')
    
    def loadfile(self):
        #用按钮读取文件
        try:
            self.pb.setText(self.fname[0])
            data_path = self.fname[0]
            data_path = data_path.replace('/','\\''\\')
            self.data = robjects.r('''read.csv("%s", na.strings=c("."))''' %data_path)
            #在R环境里创建一个dataset
            fname_in_global = self.fname[0].split('/') #将路径分成以\\隔开的列表
            robjects.globalenv['%s'%fname_in_global[-1]] = self.data
            QMessageBox.information(self,'提示','数据上传成功！',QMessageBox.Ok,QMessageBox.Ok)
        except:
            pass

    def create_it(self):
        #创建模型
        self.modelname = self.ode_a.modelname.text()
        #修改格式函数
        def add_space(num, list):
            l = []
            for x in list:
                x = num * ' ' + x
                l.append(x)
            return l
        modelsetting = self.ode_a.modelsetting.toPlainText()
        modelsetting = modelsetting.strip().split('\n')
        modelsetting = add_space(4,modelsetting)
        self.modelsetting = '\n'.join(modelsetting)
        # print(self.modelsetting)
        
        modelformula = self.ode_a.modelformula.toPlainText()
        modelformula = modelformula.strip().split('\n')
        modelformula = add_space(4,modelformula)
        self.modelformula = '\n'.join(modelformula)
        # print(self.modelformula)
        
        model = '''%s <- function() {
  ini({
%s
  })
  model({
%s
  })
}'''%(self.modelname, self.modelsetting, self.modelformula)
        # print(model)
        try:
            self.model = robjects.r('''%s''' %model)
        except:
            QMessageBox.critical(self,'提示','模型创建失败,请检查输入内容是否正确!',QMessageBox.Ok,QMessageBox.Ok)
        # print(self.model)
        else:
            QMessageBox.information(self,'提示','模型创建成功！',QMessageBox.Ok,QMessageBox.Ok)
            self.ode_a.modelname.setText('')
            self.ode_a.modelsetting.clear()
            self.ode_a.modelformula.clear()
            self.ode_a.close()

    def choose_it(self):
        #选择算法时候饭后算法名称
        self.algo = self.choose.currentText()

    def fit_it(self):
        #给函数的参数赋值
        self.beginb.setEnabled(False)
        model = self.model
        data = self.data
        algo = self.algo
        # algo = str(algo)
        print("Please wait...")
        self.result = to_fit(model, data, algo, table=tableControl(cwres=True, npde=True))
        robjects.globalenv['fit.'+self.modelname] = self.result
        # print(result)
        #把数据保存到本地output.txt文本中
        f = open(r'output.txt','w+')
        print(self.result,file=f)
        f.close()  
        #读取本地文本
        f = open('output.txt','r')
        contents = f.read()
        self.fit_result.text.setText(contents)
        self.beginb.setEnabled(True)
        print('Finished!')
        #删除本地文本缓存
        # os.remove('output.txt')
    
    def display_fit_data(self):
        self.display_fit_data = robjects.r('''write.csv(%s, file="%s", quote = F, na = ".", row.names = F)''' %('fit.'+self.modelname,'fit.'+self.modelname+'.csv'))
        QMessageBox.information(self,'提示','已保存至当前工作目录下',QMessageBox.Ok,QMessageBox.Ok)
    
    def clean_fit_result(self):
        self.fit_result.text.setText('')
    
    # @classmethod
    # def return_data_in_r(cls):
    #     return cls.data_in_r
        # self.fit_result = robjects.globalenv['fit.'+self.modelname]
        # self.fit_result.to_csvfile(path = r(fit_result_save_path))
